/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.lucene.gradle.plugins.misc;

import com.carrotsearch.gradle.buildinfra.dependencychecks.DependencyChecksPlugin;
import com.carrotsearch.gradle.buildinfra.dependencychecks.DependencyVersionChecksExtension;
import java.util.Set;
import org.apache.lucene.gradle.plugins.LuceneGradlePlugin;
import org.gradle.api.Project;

/**
 * Configure dependency checks plugin which validates and updates the top-level {@code
 * versions.lock}, taking care of cross-configuration consistency of transitive dependencies.
 *
 * @see "https://github.com/apache/lucene/blob/main/help/dependencies.txt"
 * @see
 *     "https://github.com/carrotsearch/gradle-build-infra#plugin-comcarrotsearchgradlebuildinfradependencychecksdependencychecksplugin"
 */
public class ConfigureLockFilePlugin extends LuceneGradlePlugin {

  @Override
  public void apply(Project rootProject) {
    applicableToRootProjectOnly(rootProject);

    rootProject.allprojects(
        project -> {
          // We don't care about the build infra deps in the lock file.
          if (project.getPath().equals(":build-tools:build-infra-shadow")) {
            return;
          }

          configureLockFile(project);
        });
  }

  private void configureLockFile(Project project) {
    project.getPlugins().apply(DependencyChecksPlugin.class);

    Set<String> includedMainConfigurations = Set.of("compileClasspath", "runtimeClasspath");
    Set<String> includedTestConfigurations =
        Set.of("annotationProcessor", "testCompileClasspath", "testRuntimeClasspath");

    var mainConfigurations =
        project
            .getConfigurations()
            .matching(conf -> includedMainConfigurations.contains(conf.getName()));

    var testConfigurations =
        project
            .getConfigurations()
            .matching(conf -> includedTestConfigurations.contains(conf.getName()));

    var ext = project.getExtensions().getByType(DependencyVersionChecksExtension.class);
    ext.getLockFileComment()
        .set("An inventory of resolved dependency versions. Do not edit this file directly.");

    var configurationGroups = ext.getConfigurationGroups();
    configurationGroups.create("main_dependencies").include(mainConfigurations);
    configurationGroups.create("test_dependencies").include(testConfigurations);
  }
}
